package com.sk.utility;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;

import org.apache.commons.io.IOUtils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

/**
 * @author saurabh Persists downloaded images on local storage to prevent
 *         downloading again
 */
public class FileCache {
	private File cacheDir;

	public FileCache(Context context) {
		if (android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED))
			cacheDir = new File(
					android.os.Environment.getExternalStorageDirectory(),
					Constants.urlFileCacheURL);
		else
			cacheDir = context.getCacheDir();
		if (!cacheDir.exists()) {
			cacheDir.mkdirs();
		}
		File file = new File(cacheDir, ".nomedia");
		try {
			touch(file);
		} catch (IOException e) {
			Log.e("FileCache", e.getMessage());

		}
	}

	public File getFileName(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(cacheDir, filename);
		return f;

	}

	public String getFile(File file) {

		String retFeed = null;
		FileInputStream is = null;
		try {
			is = new FileInputStream(file);
			retFeed = IOUtils.toString(is, "UTF-8");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(is);
		}
		return retFeed;
	}

	public Bitmap getFile(File file, int screenWidth) {
		final Bitmap bmp = decodeFile(file, screenWidth);
		return bmp;
	}

	public void putFile(Hashtable<String, String> feedWrapper) {
		File f = getFileName(feedWrapper.get("url"));
		writeToSD(feedWrapper.get("feed"), f);
	}

	public void putFile(String url, Bitmap bmp) {
		File f = getFileName(url);
		writeToSD(bmp, f);
	}

	/**
	 * Writes string feed to disk
	 * 
	 * @param str
	 * @param file
	 */
	private void writeToSD(String str, File file) {
		try {
			if (!file.exists()) {
				file.createNewFile();
			}
			FileOutputStream out = new FileOutputStream(file, false);
			out.write(str.getBytes());
			out.flush();
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Writes compressed BMP to disk
	 * 
	 * @param bmp
	 * @param file
	 */
	private void writeToSD(Bitmap bmp, File file) {
		try {
			file.createNewFile();
			FileOutputStream out = new FileOutputStream(file);
			bmp.compress(Bitmap.CompressFormat.JPEG, 80, out);
			out.flush();
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private Bitmap decodeFile(File f, int screenWidth) {
		try {
			if (f.exists()) {
				BitmapFactory.Options o = new BitmapFactory.Options();
				o.inJustDecodeBounds = true;
				BitmapFactory.decodeStream(new FileInputStream(f), null, o);
				int REQUIRED_SIZE = screenWidth;
				if (screenWidth < REQUIRED_SIZE) {
					REQUIRED_SIZE = screenWidth;
				}
				int width_tmp = o.outWidth, height_tmp = o.outHeight;
				int scale = 1;
				while (true) {
					if (width_tmp / 2 < REQUIRED_SIZE
							|| height_tmp / 2 < REQUIRED_SIZE)
						break;
					width_tmp /= 2;
					height_tmp /= 2;
					scale *= 2;
				}
				BitmapFactory.Options o2 = new BitmapFactory.Options();
				o2.inSampleSize = scale;
				return BitmapFactory.decodeStream(new FileInputStream(f), null,
						o2);
			}
		} catch (FileNotFoundException e) {
			Log.e("ImageSource", "File not found!");
		}
		return null;
	}

	public void clear() {
		File[] files = cacheDir.listFiles();
		if (files == null)
			return;
		for (File f : files)
			f.delete();
	}

	public static void touch(File file) throws IOException {
		if (!file.exists()) {
			File parent = file.getParentFile();
			if (parent != null)
				if (!parent.exists())
					if (!parent.mkdirs())
						throw new IOException(
								"Cannot create parent directories for file: "
										+ file);
			file.createNewFile();
		}
		boolean success = file.setLastModified(System.currentTimeMillis());
		if (!success)
			throw new IOException(
					"Unable to set the last modification time for " + file);
	}
}